package org.httpclient.spring.boot.autoconfigure;

import java.util.concurrent.TimeUnit;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.IdleConnectionEvictor;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

/**
 * 注入httpclient连接池配置
 * 
 * @author chenfanglin
 * @date: 2018年8月15日 下午7:25:37
 */
@Configuration
@EnableConfigurationProperties(HttpClientPoolProperties.class)
public class HttpClientPoolAutoConfiguration {

	@Autowired
	private HttpClientPoolProperties httpClientPoolProperties;

	/**
	 * 实例化连接池管理器
	 * 
	 * @return
	 */
	@Bean(name = "connectionManager", destroyMethod = "close")
	public PoolingHttpClientConnectionManager connectionManager() {
		PoolingHttpClientConnectionManager pooltccm = new PoolingHttpClientConnectionManager();
		pooltccm.setMaxTotal(httpClientPoolProperties.getMaxTotal());
		pooltccm.setDefaultMaxPerRoute(httpClientPoolProperties.getDefaultMaxPerRoute());
		return pooltccm;
	}

	/**
	 * 实例化httpClient对象，多例模式
	 * 
	 * @return
	 */
	@Bean(name = "httpClient")
	@Scope("prototype")
	public CloseableHttpClient httpClient() {
		HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
		httpClientBuilder.setConnectionManager(connectionManager());
		return httpClientBuilder.build();
	}

	/**
	 * 实例化请求配置信息构建器
	 * 
	 * @return
	 */
	@Bean(name = "requestConfigBuilder")
	public Builder requestConfigBuilder() {
		Builder builder = RequestConfig.custom();
		builder.setConnectTimeout(httpClientPoolProperties.getConnectTimeout());
		builder.setConnectionRequestTimeout(httpClientPoolProperties.getConnectionRequestTimeout());
		builder.setSocketTimeout(httpClientPoolProperties.getSocketTimeout());
		return builder;
	}

	/**
	 * 实例化请求配置
	 * 
	 * @return
	 */
	@Bean(name = "requestConfig")
	public RequestConfig requestConfig() {
		return requestConfigBuilder().build();
	}

	/**
	 * 定时清理Connection
	 * 
	 * @return
	 */
	@Bean(name = "httpclientPoolingCycleClear", destroyMethod = "shutdown")
	public IdleConnectionEvictor idleConnectionEvictor() {
		IdleConnectionEvictor idleConnectionEvictor = new IdleConnectionEvictor(connectionManager(),
				httpClientPoolProperties.getMaxIdleTimeMs(), TimeUnit.MILLISECONDS);
		return idleConnectionEvictor;
	}
}
